// *************************************************************************************************
//
// MK3D Engine
// --------------------------------------
// Copyright (C) 2007-2011 Zeb (mailto: zebbey@gmail.com)
//
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//
// *************************************************************************************************

#ifndef __H_MK_TERRAIN_REGION__
#define __H_MK_TERRAIN_REGION__

#include "mk_mesh.h"
#include "mk_aabb.h"

namespace MK3DE
{
	const float TERRAIN_CELL_WIDTH = 100.0f;
	const float TERRAIN_CELL_HEIGHT = 100.0f;
	const DWORD TERRAIN_REGION_WIDTH = 16;
	const DWORD TERRAIN_REGION_HEIGHT = 16;
	const DWORD TERRAIN_REGION_WIDTH_VERTEX = 17;
	const DWORD TERRAIN_REGION_HEIGHT_VERTEX = 17;
	const float TERRAIN_REGION_WIDTH_SIZE = (float)TERRAIN_CELL_WIDTH * TERRAIN_REGION_WIDTH;
	const float TERRAIN_REGION_HEIGHT_SIZE = (float)TERRAIN_CELL_HEIGHT * TERRAIN_REGION_HEIGHT;
	const DWORD TERRAIN_REGION_VERTEX_COUNT = TERRAIN_REGION_WIDTH_VERTEX * TERRAIN_REGION_HEIGHT_VERTEX;
	const DWORD TERRAIN_REGION_FACE_COUNT = TERRAIN_REGION_WIDTH * TERRAIN_REGION_HEIGHT * 2;

	const DWORD REGION_IDX_UP = 0;
	const DWORD REGION_IDX_RIGHT = 1;
	const DWORD REGION_IDX_DOWN = 2;
	const DWORD REGION_IDX_LEFT = 3;

	const DWORD TERRAIN_INDEX_L0_0[] = {
		0, 17, 1, 17, 18, 1, 1, 18, 2, 18, 19, 2, 2, 19, 3, 19, 20, 3, 
		3, 20, 4, 20, 21, 4, 4, 21, 5, 21, 22, 5, 5, 22, 6, 22, 23, 6, 
		6, 23, 7, 23, 24, 7, 7, 24, 8, 24, 25, 8, 8, 25, 9, 25, 26, 9, 
		9, 26, 10, 26, 27, 10, 10, 27, 11, 27, 28, 11, 11, 28, 12, 28, 29, 12, 
		12, 29, 13, 29, 30, 13, 13, 30, 14, 30, 31, 14, 14, 31, 15, 31, 32, 15, 
		15, 32, 16, 32, 33, 16, 17, 34, 18, 34, 35, 18, 18, 35, 19, 35, 36, 19, 
		19, 36, 20, 36, 37, 20, 20, 37, 21, 37, 38, 21, 21, 38, 22, 38, 39, 22, 
		22, 39, 23, 39, 40, 23, 23, 40, 24, 40, 41, 24, 24, 41, 25, 41, 42, 25, 
		25, 42, 26, 42, 43, 26, 26, 43, 27, 43, 44, 27, 27, 44, 28, 44, 45, 28, 
		28, 45, 29, 45, 46, 29, 29, 46, 30, 46, 47, 30, 30, 47, 31, 47, 48, 31, 
		31, 48, 32, 48, 49, 32, 32, 49, 33, 49, 50, 33, 34, 51, 35, 51, 52, 35, 
		35, 52, 36, 52, 53, 36, 36, 53, 37, 53, 54, 37, 37, 54, 38, 54, 55, 38, 
		38, 55, 39, 55, 56, 39, 39, 56, 40, 56, 57, 40, 40, 57, 41, 57, 58, 41, 
		41, 58, 42, 58, 59, 42, 42, 59, 43, 59, 60, 43, 43, 60, 44, 60, 61, 44, 
		44, 61, 45, 61, 62, 45, 45, 62, 46, 62, 63, 46, 46, 63, 47, 63, 64, 47, 
		47, 64, 48, 64, 65, 48, 48, 65, 49, 65, 66, 49, 49, 66, 50, 66, 67, 50, 
		51, 68, 52, 68, 69, 52, 52, 69, 53, 69, 70, 53, 53, 70, 54, 70, 71, 54, 
		54, 71, 55, 71, 72, 55, 55, 72, 56, 72, 73, 56, 56, 73, 57, 73, 74, 57, 
		57, 74, 58, 74, 75, 58, 58, 75, 59, 75, 76, 59, 59, 76, 60, 76, 77, 60, 
		60, 77, 61, 77, 78, 61, 61, 78, 62, 78, 79, 62, 62, 79, 63, 79, 80, 63, 
		63, 80, 64, 80, 81, 64, 64, 81, 65, 81, 82, 65, 65, 82, 66, 82, 83, 66, 
		66, 83, 67, 83, 84, 67, 68, 85, 69, 85, 86, 69, 69, 86, 70, 86, 87, 70, 
		70, 87, 71, 87, 88, 71, 71, 88, 72, 88, 89, 72, 72, 89, 73, 89, 90, 73, 
		73, 90, 74, 90, 91, 74, 74, 91, 75, 91, 92, 75, 75, 92, 76, 92, 93, 76, 
		76, 93, 77, 93, 94, 77, 77, 94, 78, 94, 95, 78, 78, 95, 79, 95, 96, 79, 
		79, 96, 80, 96, 97, 80, 80, 97, 81, 97, 98, 81, 81, 98, 82, 98, 99, 82, 
		82, 99, 83, 99, 100, 83, 83, 100, 84, 100, 101, 84, 85, 102, 86, 102, 103, 86, 
		86, 103, 87, 103, 104, 87, 87, 104, 88, 104, 105, 88, 88, 105, 89, 105, 106, 89, 
		89, 106, 90, 106, 107, 90, 90, 107, 91, 107, 108, 91, 91, 108, 92, 108, 109, 92, 
		92, 109, 93, 109, 110, 93, 93, 110, 94, 110, 111, 94, 94, 111, 95, 111, 112, 95, 
		95, 112, 96, 112, 113, 96, 96, 113, 97, 113, 114, 97, 97, 114, 98, 114, 115, 98, 
		98, 115, 99, 115, 116, 99, 99, 116, 100, 116, 117, 100, 100, 117, 101, 117, 118, 101, 
		102, 119, 103, 119, 120, 103, 103, 120, 104, 120, 121, 104, 104, 121, 105, 121, 122, 105, 
		105, 122, 106, 122, 123, 106, 106, 123, 107, 123, 124, 107, 107, 124, 108, 124, 125, 108, 
		108, 125, 109, 125, 126, 109, 109, 126, 110, 126, 127, 110, 110, 127, 111, 127, 128, 111, 
		111, 128, 112, 128, 129, 112, 112, 129, 113, 129, 130, 113, 113, 130, 114, 130, 131, 114, 
		114, 131, 115, 131, 132, 115, 115, 132, 116, 132, 133, 116, 116, 133, 117, 133, 134, 117, 
		117, 134, 118, 134, 135, 118, 119, 136, 120, 136, 137, 120, 120, 137, 121, 137, 138, 121, 
		121, 138, 122, 138, 139, 122, 122, 139, 123, 139, 140, 123, 123, 140, 124, 140, 141, 124, 
		124, 141, 125, 141, 142, 125, 125, 142, 126, 142, 143, 126, 126, 143, 127, 143, 144, 127, 
		127, 144, 128, 144, 145, 128, 128, 145, 129, 145, 146, 129, 129, 146, 130, 146, 147, 130, 
		130, 147, 131, 147, 148, 131, 131, 148, 132, 148, 149, 132, 132, 149, 133, 149, 150, 133, 
		133, 150, 134, 150, 151, 134, 134, 151, 135, 151, 152, 135, 136, 153, 137, 153, 154, 137, 
		137, 154, 138, 154, 155, 138, 138, 155, 139, 155, 156, 139, 139, 156, 140, 156, 157, 140, 
		140, 157, 141, 157, 158, 141, 141, 158, 142, 158, 159, 142, 142, 159, 143, 159, 160, 143, 
		143, 160, 144, 160, 161, 144, 144, 161, 145, 161, 162, 145, 145, 162, 146, 162, 163, 146, 
		146, 163, 147, 163, 164, 147, 147, 164, 148, 164, 165, 148, 148, 165, 149, 165, 166, 149, 
		149, 166, 150, 166, 167, 150, 150, 167, 151, 167, 168, 151, 151, 168, 152, 168, 169, 152, 
		153, 170, 154, 170, 171, 154, 154, 171, 155, 171, 172, 155, 155, 172, 156, 172, 173, 156, 
		156, 173, 157, 173, 174, 157, 157, 174, 158, 174, 175, 158, 158, 175, 159, 175, 176, 159, 
		159, 176, 160, 176, 177, 160, 160, 177, 161, 177, 178, 161, 161, 178, 162, 178, 179, 162, 
		162, 179, 163, 179, 180, 163, 163, 180, 164, 180, 181, 164, 164, 181, 165, 181, 182, 165, 
		165, 182, 166, 182, 183, 166, 166, 183, 167, 183, 184, 167, 167, 184, 168, 184, 185, 168, 
		168, 185, 169, 185, 186, 169, 170, 187, 171, 187, 188, 171, 171, 188, 172, 188, 189, 172, 
		172, 189, 173, 189, 190, 173, 173, 190, 174, 190, 191, 174, 174, 191, 175, 191, 192, 175, 
		175, 192, 176, 192, 193, 176, 176, 193, 177, 193, 194, 177, 177, 194, 178, 194, 195, 178, 
		178, 195, 179, 195, 196, 179, 179, 196, 180, 196, 197, 180, 180, 197, 181, 197, 198, 181, 
		181, 198, 182, 198, 199, 182, 182, 199, 183, 199, 200, 183, 183, 200, 184, 200, 201, 184, 
		184, 201, 185, 201, 202, 185, 185, 202, 186, 202, 203, 186, 187, 204, 188, 204, 205, 188, 
		188, 205, 189, 205, 206, 189, 189, 206, 190, 206, 207, 190, 190, 207, 191, 207, 208, 191, 
		191, 208, 192, 208, 209, 192, 192, 209, 193, 209, 210, 193, 193, 210, 194, 210, 211, 194, 
		194, 211, 195, 211, 212, 195, 195, 212, 196, 212, 213, 196, 196, 213, 197, 213, 214, 197, 
		197, 214, 198, 214, 215, 198, 198, 215, 199, 215, 216, 199, 199, 216, 200, 216, 217, 200, 
		200, 217, 201, 217, 218, 201, 201, 218, 202, 218, 219, 202, 202, 219, 203, 219, 220, 203, 
		204, 221, 205, 221, 222, 205, 205, 222, 206, 222, 223, 206, 206, 223, 207, 223, 224, 207, 
		207, 224, 208, 224, 225, 208, 208, 225, 209, 225, 226, 209, 209, 226, 210, 226, 227, 210, 
		210, 227, 211, 227, 228, 211, 211, 228, 212, 228, 229, 212, 212, 229, 213, 229, 230, 213, 
		213, 230, 214, 230, 231, 214, 214, 231, 215, 231, 232, 215, 215, 232, 216, 232, 233, 216, 
		216, 233, 217, 233, 234, 217, 217, 234, 218, 234, 235, 218, 218, 235, 219, 235, 236, 219, 
		219, 236, 220, 236, 237, 220, 221, 238, 222, 238, 239, 222, 222, 239, 223, 239, 240, 223, 
		223, 240, 224, 240, 241, 224, 224, 241, 225, 241, 242, 225, 225, 242, 226, 242, 243, 226, 
		226, 243, 227, 243, 244, 227, 227, 244, 228, 244, 245, 228, 228, 245, 229, 245, 246, 229, 
		229, 246, 230, 246, 247, 230, 230, 247, 231, 247, 248, 231, 231, 248, 232, 248, 249, 232, 
		232, 249, 233, 249, 250, 233, 233, 250, 234, 250, 251, 234, 234, 251, 235, 251, 252, 235, 
		235, 252, 236, 252, 253, 236, 236, 253, 237, 253, 254, 237, 238, 255, 239, 255, 256, 239, 
		239, 256, 240, 256, 257, 240, 240, 257, 241, 257, 258, 241, 241, 258, 242, 258, 259, 242, 
		242, 259, 243, 259, 260, 243, 243, 260, 244, 260, 261, 244, 244, 261, 245, 261, 262, 245, 
		245, 262, 246, 262, 263, 246, 246, 263, 247, 263, 264, 247, 247, 264, 248, 264, 265, 248, 
		248, 265, 249, 265, 266, 249, 249, 266, 250, 266, 267, 250, 250, 267, 251, 267, 268, 251, 
		251, 268, 252, 268, 269, 252, 252, 269, 253, 269, 270, 253, 253, 270, 254, 270, 271, 254, 
		255, 272, 256, 272, 273, 256, 256, 273, 257, 273, 274, 257, 257, 274, 258, 274, 275, 258, 
		258, 275, 259, 275, 276, 259, 259, 276, 260, 276, 277, 260, 260, 277, 261, 277, 278, 261, 
		261, 278, 262, 278, 279, 262, 262, 279, 263, 279, 280, 263, 263, 280, 264, 280, 281, 264, 
		264, 281, 265, 281, 282, 265, 265, 282, 266, 282, 283, 266, 266, 283, 267, 283, 284, 267, 
		267, 284, 268, 284, 285, 268, 268, 285, 269, 285, 286, 269, 269, 286, 270, 286, 287, 270, 
		270, 287, 271, 287, 288, 271, 
	};

	class CTerrainHeightBrush;

	class MK3DE_API CTerrainRegion
	{
		friend class CEntityTerrainRegion;

	public:
		typedef struct  
		{
			std::vector<CMesh::Position>        vecPosition;
			std::vector<CMesh::Normal>          vecNormal;
			std::vector<CMesh::TextureCoord>    vecTexCoord;

			std::vector<CMesh::Normal>          vecFaceNormal;
		} TerrainData;

	public:
		CTerrainRegion();
		~CTerrainRegion();

		BOOL CreateMesh(int regionX, int regionY);

		BOOL LoadHeightMap(const char* fileName);
		BOOL SaveHeightMap(const char* fileName);

		void AttachNeighboringRegion(CTerrainRegion* Up, CTerrainRegion* Right, 
			CTerrainRegion* Down, CTerrainRegion* Left);

		CTerrainRegion* GetNeighboringRegion(DWORD idx);

		BOOL GetFaceNormal(CMesh::Normal& normal, DWORD x, DWORD y, DWORD idx);

		void RecalculateNormal();
		void RecalculateFaceNormal();

		BOOL FillPositionBuffer(CMesh::Position* pPos, int vertexNum);
		BOOL FillNormalBuffer(CMesh::Normal* pNormal, int vertexNum);
		BOOL FillTextureCoordBuffer(CMesh::TextureCoord* pUV, int vertexNum);

		BOOL FillFaceBuffer(CMesh::Face* pFace, int faceNum);

		BOOL GetVertexPosition(D3DXVECTOR3& pos, DWORD x, DWORD y);
		BOOL SetVertexPosition(D3DXVECTOR3& pos, DWORD x, DWORD y);

		BOOL CollideWithRay(D3DXVECTOR3& pos, float x, float y, float z, D3DXVECTOR3& dir);

	private:
		void __ClearTerrainData();
		BOOL __GetFaceNormal(CMesh::Normal& normal, int x, int y, DWORD idx);

	private:
		TerrainData _terrainData;

		//!< Neighboring regions. Up, Right, Down, Left.
		CTerrainRegion* _neighboringRegion[4];
	};
};

#endif // __H_MK_TERRAIN_REGION__